package com.fptt;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;


public class DataSet 
{
	private List<DataPoint> dataList;
	private Map<String, DataPoint> dataMap;
	
	private Date startDate;
	private Date endDate;
	private DataPoint currentDataPoint;
	
	private int dataSize = 0;
	private String dataType = Constants.EMPTY_STR;
	private String filePath = Constants.EMPTY_STR;
	
	// Exponential Mean Average (EMA) variables
	private List<Integer> NList;
	private Map<Integer, Double> startingEMAVals = new HashMap<Integer, Double>();
	private Map<Integer, Double> previousEMAList;
				
	public DataSet (Date startDate, Date endDate, String dataType, String filePath)
	{
		this.startDate = startDate;
		this.endDate = endDate;
		this.dataType = dataType;
		this.filePath = filePath;
		
		dataList = new ArrayList<DataPoint>();
		dataMap = new HashMap<String, DataPoint>();
		
		NList = new ArrayList<Integer>(Arrays.asList(3,7,50));
		previousEMAList = new HashMap<Integer, Double>();
		
		// For data starting at 01/01/2000
		startingEMAVals.put(3, 1.1699);
		startingEMAVals.put(7, 1.169907);
		startingEMAVals.put(50, 1.170598);
		
		loadData();		
	}
	
	public void loadData()
	{
		try
		{
			dataList.clear();
			dataSize = dataList.size();
			dataMap.clear();
			
			FileInputStream fstream = new FileInputStream(filePath);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			
			String strLine = "";
			Date currDate = null;
			
			int i = 0;
			for (Integer N : NList) {previousEMAList.put(N, 0.0);}

			// Read all historical data into the DataSet
			while ((strLine = br.readLine()) != null)   
			{
				Scanner lineScan = new Scanner (strLine);
				lineScan.useDelimiter("\t");
				String date = lineScan.next();
				if (!date.equals("Time"))
				{
					currDate = Constants.ddmmyyyyDotHDateFormat.parse(date); 

					Calendar calendar = Calendar.getInstance();
					calendar.setTime(currDate);

					String open = lineScan.next();
					String high = lineScan.next();
					String low = lineScan.next();
					String close = lineScan.next();
					Double volume = Double.valueOf(lineScan.next());

					if (volume != 0)
					{
						DataPoint dataPoint = new DataPoint ();
						
						dataPoint.setDate(currDate);
						dataPoint.setOpen(Double.valueOf(open));
						dataPoint.setHigh(Double.valueOf(high));
						dataPoint.setLow(Double.valueOf(low));
						
						double todayClose = Double.valueOf(close);
						dataPoint.setClose(todayClose);
						
						for (Integer N : NList)
						{
							// We need the simple moving average
							if (i == 0)
							{
								double prevEMAVal = startingEMAVals.get(N);	
								double tempEMAVal = Utilities.calculateEMA(N, todayClose, prevEMAVal);	

								dataPoint.getEmaMap().put(N, tempEMAVal);
								dataPoint.getEmaList().add(tempEMAVal);
							}
							else
							{
								double tempEMAVal = Utilities.calculateEMA(N, todayClose, previousEMAList.get(N));	
								dataPoint.getEmaMap().put(N, tempEMAVal);
								dataPoint.getEmaList().add(tempEMAVal);
								previousEMAList.put(N, tempEMAVal);
							}
						}
						
						dataPoint.setVolume(volume);
						dataPoint.setDataPointNum(i++);
						dataPoint.setEmaTrend(Utilities.determineEMATrend(dataPoint.getEmaList()));
						dataPoint.setMaxEmaDiff(Utilities.determineMaxEmaDiff(dataPoint.getEmaList()));
						
						dataList.add(dataPoint);
						
						dataMap.put(Constants.mmddyyyyHDateFormat.format(currDate), dataPoint);
					}
				}
			}
			
			in.close();
		}
		catch (Exception e)
		{
			System.err.println("Error: " + e.getMessage());
		}
		
		dataSize = dataList.size();
	}
	
	public List<DataPoint> getData() {
		return dataList;
	}

	public void setData(List<DataPoint> data) {
		this.dataList = data;
	}

	public Map<String, DataPoint> getDataMap() {
		return dataMap;
	}

	public void setDataMap(Map<String, DataPoint> dataMap) {
		this.dataMap = dataMap;
	}

	public Date getStartDate() {
		return startDate;
	}

	public void setStartDate(Date startDate) {
		this.startDate = startDate;
	}

	public Date getEndDate() {
		return endDate;
	}

	public void setEndDate(Date endDate) {
		this.endDate = endDate;
	}

	public DataPoint getCurrentDataPoint() {
		return currentDataPoint;
	}

	public void setCurrentDataPoint(DataPoint currentDay) {
		this.currentDataPoint = currentDay;
	}

	public int getDataSize() {
		return dataSize;
	}

	public void setDataSize(int dataSize) {
		this.dataSize = dataSize;
	}
	
	public DataPoint getDataPoint (Date date)
	{
		String dateStr = Constants.mmddyyyyHDateFormat.format(date);
		return dataMap.get(dateStr);
	}

	public Map<Integer, Double> getPreviousEMAList() {
		return previousEMAList;
	}

	public void setPreviousEMAList(Map<Integer, Double> yesterdayEMAList) {
		this.previousEMAList = yesterdayEMAList;
	}

	public List<DataPoint> getDataList() {
		return dataList;
	}

	public void setDataList(List<DataPoint> dataList) {
		this.dataList = dataList;
	}

	public List<Integer> getNList() {
		return NList;
	}
}
